<template>
  <div>
    <div>
      <div ref="container" class="w-full h-screen bg-gray-100"></div>
    </div>
  </div>
</template>

<script setup>
import { onMounted, ref } from "vue";
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";

onMounted(() => {
  init();
});

const container = ref(null);
let scene, camera, renderer;
function init() {
  // 清除之前的场景
  if (scene) {
    scene.clear();
  }

  // 1.创建场景
  scene = new THREE.Scene();
  // scene.background = new THREE.Color(0xffffff); // 设置背景颜色为白色

  //   const loader = new THREE.TextureLoader();
  //   loader.load(
  //     "https://file.supore.cn/1733456524微信图片_20240304170728.jpg",
  //     (texture) => {
  //       scene.background = texture; // 异步， 贴图
  //       // render.render(scene,camera); // 渲染  --如果没有循环，则需再次调用一下
  //     }
  //   );

  // 2.创建相机
  camera = new THREE.PerspectiveCamera(
    75, // FOV 摄像机视椎体垂直视野角度
    window.innerWidth / window.innerHeight, // 摄像机视椎体宽高比(长宽比)
    0.1, // near 摄像机视椎体近端面
    1000 // far 摄像机视椎体远端面
  );
  // 3.创建渲染器
  renderer = new THREE.WebGLRenderer({
    antialias: true, // 抗锯齿
  });

  // 4.设置渲染器尺寸并添加到 DOM
  renderer.setSize(window.innerWidth, window.innerHeight);
  container.value.appendChild(renderer.domElement);

  // 5.创建一个立方体
  const geometry = new THREE.BoxGeometry(2, 2, 2); // 5.1 立方体
  const circularCone_geometry = new THREE.ConeGeometry(1, 3, 20); // 5.2 圆形圆锥
  const round_geometry = new THREE.TorusKnotGeometry(1.5, 0.2, 10, 48); // 5.3 交叉
  const plane_geometry = new THREE.PlaneGeometry(3, 3, 5, 5); // 5.4 平面缓冲几何体
  const ball_geometry = new THREE.SphereGeometry(2, 32, 16); // 5.5 球体
  const buffer_geometry = new THREE.BufferGeometry(); // 5.6 缓冲几何体
  // -- 创建材质
  // MeshBasicMaterial 不受光照影响
  // MeshStandardMaterial 受光照影响
  const material = new THREE.MeshStandardMaterial({
    // color: 0xbe77ff, // 材质颜色
    // emissive: 0xbe77ff, //  自发光颜色
    // wireframe: true, //  线框模式
    map: new THREE.TextureLoader().load(
      "https://file.supore.cn/1724165809IMG_1115.jpeg"
    ), // 贴图
  });

  // -- 环境光和平行光
  const light = new THREE.AmbientLight(0x404040); // 柔和的白光
  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5); // 平行光
  directionalLight.position.set(3, 3, 3); // 设置光源的位置
  scene.add(light, directionalLight); // 添加到场景中

  // -- 结构和材质组合，生成一个物体
  let cube = new THREE.Mesh(geometry, material);
  cube.position.z = 6;

  let cube2 = new THREE.Mesh(
    circularCone_geometry,
    new THREE.MeshBasicMaterial({ color: 0xff0000 })
  );
  cube2.position.x = 6;

  let cube3 = new THREE.Mesh(
    round_geometry,
    new THREE.MeshBasicMaterial({ color: 0xffff00 })
  );
  cube3.position.x = -6;

  let cube4 = new THREE.Mesh(
    plane_geometry,
    new THREE.MeshBasicMaterial({ color: 0x1cda4b, wireframe: true })
  );
  cube4.position.z = -6;

  let cube5 = new THREE.Mesh(
    ball_geometry,
    new THREE.MeshStandardMaterial({
      color: 0x00ffff,
      wireframe: true,
      // roughness: 0.3, // 材质的粗糙程度
      // metalness: 0.2, // 材质的金属度
    })
  );
  // cube5.position.z = 6;

  const vertices = new Float32Array([
    -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0,

    1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0,
  ]);
  const colors = new Float32Array([
    1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,

    0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0,
  ]);
  buffer_geometry.setAttribute(
    "position",
    new THREE.BufferAttribute(vertices, 3)
  ); // 顶点 两个三角形 共六个点
  buffer_geometry.setAttribute("color", new THREE.BufferAttribute(colors, 3)); // 颜色
  let cube6 = new THREE.Mesh(
    buffer_geometry,
    new THREE.MeshBasicMaterial({ vertexColors: true, wireframe: true })
  );
  cube6.position.z = 6;
  cube6.position.x = 6;

  scene.add(cube, cube2, cube3, cube4, cube5, cube6);

  // 6.轨道控制器
  const controls = new OrbitControls(camera, renderer.domElement);
  controls.enableDamping = true; // 阻尼惯性
  controls.rotateSpeed = 1; // 旋转速度
  controls.update();
  camera.addEventListener("change", () => {
    renderer.render(scene, camera);
  });

  // 7.设置相机位置
  camera.position.set(0, 15, 12);
  camera.lookAt(0, 0, 0); // 摄像机视点

  // 8.添加辅助线(网格)
  const size = 20; // 网格大小
  const divisions = 20; // 网格分割数
  const gridHelper = new THREE.GridHelper(size, divisions, 0xffffff);
  scene.add(gridHelper);

  renderer.render(scene, camera);

  let angle = 0; // 初始角度
  // 渲染循环
  function animate() {
    requestAnimationFrame(animate);

    // 旋转
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;
    cube3.rotation.x -= 0.02;
    cube3.rotation.y += 0.03;
    cube4.rotation.y += 0.03;
    cube5.rotation.x -= 0.01;

    controls.rotateSpeed = 5; // 旋转速度

    controls.update(); // 更新控制器  带有拖动惯性

    // const radius = 5; // 半径
    // angle += 0.01; // 增加角度
    // camera.position.x = Math.cos(angle) * radius; // x坐标
    // camera.position.z = Math.sin(angle) * radius; // z坐标
    // camera.lookAt(0, 0, 0); // 摄像机视点

    renderer.render(scene, camera); // // 渲染场景
  }

  animate(); // 启动动画
}

// 窗口大小变化时重新调整渲染器尺寸
window.addEventListener("resize", () => {
  renderer.setSize(window.innerWidth, window.innerHeight); // 重新设置渲染器尺寸
  camera.aspect = window.innerWidth / window.innerHeight; // 更新相机的宽高比
  camera.updateProjectionMatrix(); // 更新相机投影矩阵
});
</script>